#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<pthread.h>
#include"InetAddr.hpp"
#include"ThreadPool.hpp"
#include"LockGuard.hpp"
//路由功能
using task_t =std::function<void()>;
// typedef std::function<void()> task_t ;

class Route
{
    public:
        Route()
        {
            pthread_mutex_init(&mutex,nullptr);


        }  
        void CheckOnlineUser(InetAddr & who)
        {   LockGuard lockguarf(&mutex);
            for( auto & user :_online_user)
            {
                if(user==who)
                {
                    LOG(DEBUG,"%s is exist\n",who.AddrStr().c_str());
                    return ;
                }

            }
            LOG(DEBUG,"%s is not exist add it\n",who.AddrStr().c_str());
            _online_user.push_back(who);
        }
        void Offline(InetAddr&who)
        {
            auto iter=_online_user.begin();
            for(;iter!=_online_user.end();iter++)
            {
                if(*iter==who)
                {
                    LOG(DEBUG,"%s is offline\n",who.AddrStr().c_str());
                    _online_user.erase(iter);
                    break;
                }

            }
        }
        void ForwardHelper(int sockfd,const std::string &message,InetAddr who)
        {
             LockGuard lockguarf(&mutex);
             std::string send_message="["+who.AddrStr()+"]#"+message;
            for(auto & user:_online_user)

            {
                 struct sockaddr_in peer = user.Addr();
                // sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr*)&user.Addr(),sizeof(user.Addr()));
                LOG(DEBUG,"Forward message to %s come from %s message is  %s\n",user.AddrStr().c_str(),who.AddrStr(),message.c_str());
                sendto(sockfd,send_message.c_str(),send_message.size(),0,(struct sockaddr*)&peer,sizeof(peer));
            }

        }
        void Forward( int sockfd,const std::string &message,InetAddr &who)
        {
            //1.该用户是否在用户列表中，不在添加，
            CheckOnlineUser(who);
            //1.1message==”quIt||“Q"            
            if(message=="QUIT"||message=="Q")
            {
                Offline(who);
            }
            //2.用户一定在列表内
            task_t t = std::bind(&Route::ForwardHelper,this,sockfd,message,who);
            ThreadPool<task_t>::GetInstance()->Equeue(t);



        }
        ~Route()
        {
            pthread_mutex_destroy(&mutex);
        }

    private:
    std::vector<InetAddr> _online_user;
    pthread_mutex_t mutex;

 


};
